/**
 * Copyright (C) 2025  粤港澳大湾区（广东）国创中心
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, see <https://www.gnu.org/licenses/>.
 */
#include "NctiGmshInterface.h"
#include "NctiFunctionInterface.h"
#include "NctiDisplayModelBody.h"
#include "NctiDisplayDocCustomContainer.h"

#include "NctiGmshPubfun.h"
#include "NctiString.h"
#include <NctiOCCBody.h>


using namespace NCTI;

#define NCTI_OBJ_NAME "NctiGmshInterface"
NCTI_PLUGIN_DEF(NctiGmshInterface, NctiMeshFunctionInterface, "ncti_plugin_gmsh", NCTI_OBJ_NAME)

#define NCTI_DOC_MESH_TYPE(DOC_MESH_VALUE)\
if (DOC_MESH_VALUE == nullptr)\
	return NctiModelFunctionResult();\
const char* ch = DOC_MESH_VALUE->GetMeshDocType();\
if (NctiString::same(ch, "ncti_doc_gmsh_type") == false)\
	return NctiModelFunctionResult();

NctiGmshInterface* g_GmshInterface = NCTI_NEW NctiGmshInterface();

NCTI::NctiGmshInterface::NctiGmshInterface()
{

}

NCTI::NctiGmshInterface::~NctiGmshInterface()
{

}

void NCTI::NctiGmshInterface::Init()
{
	//gmsh::initialize();
}

void NCTI::NctiGmshInterface::Release()
{
	//gmsh::finalize();
}

NctiModelFunctionResult NCTI::NctiGmshInterface::create_volume_mesh_from_geometry(
    NctiDisplayDocCustomContainer* i_pCustomContainer,
    NctiDisplayModelBody* pModelObj,
    Ncti_Mesh_Option op,
    std::vector<Ncti_Float>& pos,
    std::vector<NctiElementType>& elemType,
    std::vector<Ncti_UInteger>& elemTag,
    std::vector<Ncti_UInteger>& elemData)
{
    NCTI_DOC_MESH_TYPE(i_pCustomContainer);
    NctiModelFunctionResult ret;
    if (!pModelObj)
        return ret;

    NCTI_MODEL_TAG i_geometry = pModelObj->GetNctiBody();
    NctiOCCBody* pOCCBody = (NctiOCCBody*)i_geometry;
    NctiGmeshHelper helper(op);
    if (!helper.ImportModelOCC(i_pCustomContainer, pOCCBody))
        return ret;

    if (!helper.CalculateVolume())
        return ret;

    if (!helper.CopyResult(pos, elemType, elemTag, elemData))
        return ret;
    ret.SetResult(true);
    return ret;
}


NctiModelFunctionResult NctiGmshInterface::create_surface_mesh_from_gemetry(
    NctiDisplayDocCustomContainer* i_pCustomContainer, 
    NctiDisplayModelBody* pModelObj,
    Ncti_Mesh_Option op,
    std::vector<Ncti_Float>& pos,
    std::vector<NctiElementType>& elemType,
    std::vector<Ncti_UInteger>& elemTag,
    std::vector<Ncti_UInteger>& elemData)
{
    NCTI_DOC_MESH_TYPE(i_pCustomContainer);

    NctiModelFunctionResult ret;
    if (!pModelObj)
        return ret;

    NCTI_MODEL_TAG i_geometry = pModelObj->GetNctiBody();
    NctiOCCBody* pOCCBody = (NctiOCCBody*)i_geometry;
    NctiGmeshHelper helper(op);
    if (!helper.ImportModelOCC(i_pCustomContainer, pOCCBody))
        return ret;

    if (!helper.CalculaeSurface())
        return ret;

    if (!helper.CopyResult(pos, elemType, elemTag, elemData))
        return ret;
    ret.SetResult(true);
    return ret;
}

